﻿package frEngine.core
{
    import __AS3__.vec.*;
    import baseEngine.core.*;
    import flash.display3D.*;
    import flash.events.*;
    import flash.utils.*;
    import frEngine.loaders.resource.info.*;
    import frEngine.manager.*;
    import frEngine.shader.filters.*;

    public class FrSurface3D extends Surface3D
    {
        public var indexBufferFr:FrIndexBuffer3D;
        public var targetInfo:Info3dBase;

        public function FrSurface3D(param1:String)
        {
            super(param1);
            Resource3dManager.instance.registerSurface(this);
            return;
        }// end function

        public function addVertexDataToTargetBuffer(param1:int, param2:int, param3:Data3dInfo, param4:FrVertexBuffer3D) : FrVertexBuffer3D
        {
            this.initTargetBuffer(param4, param1, param2, param3, false);
            return param4;
        }// end function

        public function reUpload() : void
        {
            var _loc_1:BufferVo = null;
            for each (_loc_1 in this.bufferVoMap)
            {
                
                if (!_loc_1.buffer.needUpdate)
                {
                    _loc_1.buffer.toUpdate();
                }
            }
            if (!this.indexBufferFr.needUpdate)
            {
                this.indexBufferFr.toUpdate();
            }
            return;
        }// end function

        public function addVertexData(param1:int, param2:int, param3:Boolean, param4:Data3dInfo) : FrVertexBuffer3D
        {
            var _loc_5:FrVertexBuffer3D = null;
            if (param3)
            {
                _loc_5 = new FrVertexBuffer3D(this, param3);
            }
            else
            {
                _loc_5 = this.getNextValiableBuffer(param1, param2);
                var _loc_6:* = new FrVertexBuffer3D(this, param3);
                _loc_5 = new FrVertexBuffer3D(this, param3);
            }
            this.initTargetBuffer(_loc_5, param1, param2, param4, true);
            return _loc_5;
        }// end function

        private function initTargetBuffer(param1:FrVertexBuffer3D, param2:int, param3:int, param4:Data3dInfo, param5:Boolean) : void
        {
            var _loc_6:* = param1.sizePerVertex;
            param1.addVertexData(param2, param3, param4, param5);
            var _loc_7:* = param1.bufferVoMap[param2];
            this.bufferVoMap[param2] = _loc_7;
            _loc_7.buffer = param1;
            this.sizePerVertex = this.sizePerVertex - _loc_6 + param1.sizePerVertex;
            param1.toUpdate();
            return;
        }// end function

        public function getUseSameBufferVoList() : Dictionary
        {
            var _loc_2:BufferVo = null;
            var _loc_3:Array = null;
            var _loc_1:* = new Dictionary(false);
            for each (_loc_2 in bufferVoMap)
            {
                
                _loc_3 = _loc_1[_loc_2.buffer];
                if (_loc_3 == null)
                {
                    var _loc_6:* = new Array();
                    _loc_3 = new Array();
                    _loc_1[_loc_2.buffer] = _loc_6;
                }
                _loc_3.push(_loc_2);
            }
            return _loc_1;
        }// end function

        private function getNextValiableBuffer(param1:int, param2:int = -1) : FrVertexBuffer3D
        {
            var _loc_4:BufferVo = null;
            var _loc_3:* = this.getVertexBufferByNameId(param1);
            if (_loc_3)
            {
                if (_loc_3.bufferVoMap[param1].size == param2)
                {
                    throw new Error("请先删除后再添加：" + param1);
                }
                return _loc_3;
            }
            else
            {
                for each (_loc_4 in this.bufferVoMap)
                {
                    
                    if (_loc_4.buffer.canInsert(param1, param2))
                    {
                        return _loc_4.buffer;
                    }
                }
                return null;
            }
        }// end function

        final public function getVertexNum() : int
        {
            var _loc_1:BufferVo = null;
            for each (_loc_1 in this.bufferVoMap)
            {
                
                if (_loc_1.buffer && _loc_1.buffer.sizePerVertex != 0)
                {
                    return _loc_1.buffer.vertexVector.length / _loc_1.buffer.sizePerVertex;
                }
            }
            return 0;
        }// end function

        final public function getVertexBufferByNameId(param1:int) : FrVertexBuffer3D
        {
            if (bufferVoMap[param1])
            {
                return bufferVoMap[param1].buffer;
            }
            return null;
        }// end function

        override public function clone() : Surface3D
        {
            var _loc_1:* = new FrSurface3D(this.name + "_clone");
            _loc_1.indexBufferFr = this.indexBufferFr;
            _loc_1.firstIndex = this.firstIndex;
            _loc_1.sizePerVertex = this.sizePerVertex;
            _loc_1.bufferVoMap = this.bufferVoMap;
            return _loc_1;
        }// end function

        override public function download() : void
        {
            var _loc_1:BufferVo = null;
            if (this.bufferVoMap)
            {
                for each (_loc_1 in this.bufferVoMap)
                {
                    
                    _loc_1.buffer.dispose(true);
                }
            }
            super.download();
            return;
        }// end function

        override public function disposeImp() : void
        {
            if (this.indexBufferFr == null)
            {
                return;
            }
            this.disposeVertextBuffer();
            this.indexBufferFr.dispose();
            this.indexBufferFr = null;
            _needUpdate = false;
            super.disposeImp();
            Resource3dManager.instance.unRegisterSurface(this);
            return;
        }// end function

        override public function clear() : void
        {
            this.download();
            this.disposeVertextBuffer();
            loadedTime = uint.MAX_VALUE;
            this.indexBufferFr = new FrIndexBuffer3D(this);
            _needUpdate = false;
            super.clear();
            return;
        }// end function

        private function disposeVertextBuffer() : void
        {
            var _loc_1:BufferVo = null;
            if (this.bufferVoMap)
            {
                for each (_loc_1 in this.bufferVoMap)
                {
                    
                    _loc_1.buffer.dispose();
                }
            }
            this.bufferVoMap = new Dictionary(false);
            return;
        }// end function

        override public function contextEvent(param1:Context3D) : Boolean
        {
            var _loc_3:BufferVo = null;
            if (!_needUpdate || !this.indexBufferFr)
            {
                return false;
            }
            var _loc_2:Boolean = true;
            for each (_loc_3 in this.bufferVoMap)
            {
                
                if (_loc_3.buffer.needUpdate)
                {
                    _loc_2 = _loc_2 && _loc_3.buffer.contextEvent(param1);
                }
            }
            if (this.indexBufferFr.needUpdate)
            {
                _loc_2 = _loc_2 && this.indexBufferFr.contextEvent(param1);
            }
            if (_loc_2)
            {
                dispatchEvent(new Event("upload"));
            }
            _needUpdate = !_loc_2;
            if (_loc_2)
            {
                loadedTime = getTimer();
            }
            else
            {
                loadedTime = uint.MAX_VALUE;
            }
            return _loc_2;
        }// end function

        override public function updateBoundings() : Boundings3D
        {
            var _loc_1:Number = NaN;
            var _loc_2:Number = NaN;
            var _loc_3:Number = NaN;
            var _loc_4:Number = NaN;
            var _loc_5:Number = NaN;
            var _loc_6:Number = NaN;
            var _loc_7:Number = NaN;
            this.bounds = new Boundings3D();
            this.bounds.min.setTo(10000000, 10000000, 10000000);
            this.bounds.max.setTo(-10000000, -10000000, -10000000);
            var _loc_8:* = this.getVertexBufferByNameId(FilterName_ID.POSITION_ID);
            if (!_loc_8)
            {
                return this.bounds;
            }
            var _loc_9:* = _loc_8.vertexVector;
            var _loc_10:* = _loc_8.sizePerVertex;
            var _loc_11:* = _loc_9.length;
            var _loc_12:* = _loc_8.bufferVoMap[FilterName_ID.POSITION_ID].offset;
            while (_loc_12 < _loc_11)
            {
                
                _loc_5 = _loc_9[_loc_12];
                _loc_6 = _loc_9[(_loc_12 + 1)];
                _loc_7 = _loc_9[_loc_12 + 2];
                if (_loc_5 < this.bounds.min.x)
                {
                    this.bounds.min.x = _loc_5;
                }
                if (_loc_6 < this.bounds.min.y)
                {
                    this.bounds.min.y = _loc_6;
                }
                if (_loc_7 < this.bounds.min.z)
                {
                    this.bounds.min.z = _loc_7;
                }
                if (_loc_5 > this.bounds.max.x)
                {
                    this.bounds.max.x = _loc_5;
                }
                if (_loc_6 > this.bounds.max.y)
                {
                    this.bounds.max.y = _loc_6;
                }
                if (_loc_7 > this.bounds.max.z)
                {
                    this.bounds.max.z = _loc_7;
                }
                _loc_12 = _loc_12 + _loc_10;
            }
            this.bounds.length.x = this.bounds.max.x - this.bounds.min.x;
            this.bounds.length.y = this.bounds.max.y - this.bounds.min.y;
            this.bounds.length.z = this.bounds.max.z - this.bounds.min.z;
            this.bounds.center.x = this.bounds.length.x * 0.5 + this.bounds.min.x;
            this.bounds.center.y = this.bounds.length.y * 0.5 + this.bounds.min.y;
            this.bounds.center.z = this.bounds.length.z * 0.5 + this.bounds.min.z;
            this.bounds.radius = int(this.bounds.length.length / 2);
            return this.bounds;
        }// end function

        public function get indexVector() : Vector.<uint>
        {
            return this.indexBufferFr.indexVector;
        }// end function

        public function set indexVector(param1:Vector.<uint>) : void
        {
            this.indexBufferFr.indexVector = param1;
            return;
        }// end function

        public function set indexBytes(param1:ByteArray) : void
        {
            this.indexBufferFr.indexBytes = param1;
            return;
        }// end function

    }
}
